//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_exported import SotoCore

/// Service object for interacting with AWS EMRServerless service.
///
/// Amazon EMR Serverless is a new deployment option for Amazon EMR. Amazon EMR Serverless provides a serverless runtime environment that simplifies running analytics applications using the latest open source frameworks such as Apache Spark and Apache Hive. With Amazon EMR Serverless, you don’t have to configure, optimize, secure, or operate clusters to run applications with these frameworks. The API reference to Amazon EMR Serverless is emr-serverless. The emr-serverless prefix is used in the following scenarios:    It is the prefix in the CLI commands for Amazon EMR Serverless. For example, aws emr-serverless start-job-run.   It is the prefix before IAM policy actions for Amazon EMR Serverless. For example, "Action": ["emr-serverless:StartJobRun"]. For more information, see Policy actions for Amazon EMR Serverless.   It is the prefix used in Amazon EMR Serverless service endpoints. For example, emr-serverless.us-east-2.amazonaws.com.
public struct EMRServerless: AWSService {
    // MARK: Member variables

    /// Client used for communication with AWS
    public let client: AWSClient
    /// Service configuration
    public let config: AWSServiceConfig

    // MARK: Initialization

    /// Initialize the EMRServerless client
    /// - parameters:
    ///     - client: AWSClient used to process requests
    ///     - region: Region of server you want to communicate with. This will override the partition parameter.
    ///     - partition: AWS partition where service resides, standard (.aws), china (.awscn), government (.awsusgov).
    ///     - endpoint: Custom endpoint URL to use instead of standard AWS servers
    ///     - middleware: Middleware chain used to edit requests before they are sent and responses before they are decoded 
    ///     - timeout: Timeout value for HTTP requests
    ///     - byteBufferAllocator: Allocator for ByteBuffers
    ///     - options: Service options
    public init(
        client: AWSClient,
        region: SotoCore.Region? = nil,
        partition: AWSPartition = .aws,
        endpoint: String? = nil,
        middleware: AWSMiddlewareProtocol? = nil,
        timeout: TimeAmount? = nil,
        byteBufferAllocator: ByteBufferAllocator = ByteBufferAllocator(),
        options: AWSServiceConfig.Options = []
    ) {
        self.client = client
        self.config = AWSServiceConfig(
            region: region,
            partition: region?.partition ?? partition,
            serviceName: "EMRServerless",
            serviceIdentifier: "emr-serverless",
            serviceProtocol: .restjson,
            apiVersion: "2021-07-13",
            endpoint: endpoint,
            variantEndpoints: Self.variantEndpoints,
            errorType: EMRServerlessErrorType.self,
            middleware: middleware,
            timeout: timeout,
            byteBufferAllocator: byteBufferAllocator,
            options: options
        )
    }




    /// FIPS and dualstack endpoints
    static var variantEndpoints: [EndpointVariantType: AWSServiceConfig.EndpointVariant] {[
        [.fips]: .init(endpoints: [
            "ca-central-1": "emr-serverless-fips.ca-central-1.amazonaws.com",
            "us-east-1": "emr-serverless-fips.us-east-1.amazonaws.com",
            "us-east-2": "emr-serverless-fips.us-east-2.amazonaws.com",
            "us-gov-east-1": "emr-serverless.us-gov-east-1.amazonaws.com",
            "us-gov-west-1": "emr-serverless.us-gov-west-1.amazonaws.com",
            "us-west-1": "emr-serverless-fips.us-west-1.amazonaws.com",
            "us-west-2": "emr-serverless-fips.us-west-2.amazonaws.com"
        ])
    ]}

    // MARK: API Calls

    /// Cancels a job run.
    @Sendable
    @inlinable
    public func cancelJobRun(_ input: CancelJobRunRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> CancelJobRunResponse {
        try await self.client.execute(
            operation: "CancelJobRun", 
            path: "/applications/{applicationId}/jobruns/{jobRunId}", 
            httpMethod: .DELETE, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Cancels a job run.
    ///
    /// Parameters:
    ///   - applicationId: The ID of the application on which the job run will be canceled.
    ///   - jobRunId: The ID of the job run to cancel.
    ///   - shutdownGracePeriodInSeconds: The duration in seconds to wait before forcefully terminating the job after cancellation is requested.
    ///   - logger: Logger use during operation
    @inlinable
    public func cancelJobRun(
        applicationId: String,
        jobRunId: String,
        shutdownGracePeriodInSeconds: Int? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> CancelJobRunResponse {
        let input = CancelJobRunRequest(
            applicationId: applicationId, 
            jobRunId: jobRunId, 
            shutdownGracePeriodInSeconds: shutdownGracePeriodInSeconds
        )
        return try await self.cancelJobRun(input, logger: logger)
    }

    /// Creates an application.
    @Sendable
    @inlinable
    public func createApplication(_ input: CreateApplicationRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> CreateApplicationResponse {
        try await self.client.execute(
            operation: "CreateApplication", 
            path: "/applications", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Creates an application.
    ///
    /// Parameters:
    ///   - architecture: The CPU architecture of an application.
    ///   - autoStartConfiguration: The configuration for an application to automatically start on job submission.
    ///   - autoStopConfiguration: The configuration for an application to automatically stop after a certain amount of time being idle.
    ///   - clientToken: The client idempotency token of the application to create. Its value must be unique for each request.
    ///   - identityCenterConfiguration: The IAM Identity Center Configuration accepts the Identity Center instance parameter required to enable trusted identity propagation. This configuration allows identity propagation between integrated services and the Identity Center instance.
    ///   - imageConfiguration: The image configuration for all worker types. You can either set this parameter or imageConfiguration for each worker type in workerTypeSpecifications.
    ///   - initialCapacity: The capacity to initialize when the application is created.
    ///   - interactiveConfiguration: The interactive configuration object that enables the interactive use cases to use when running an application.
    ///   - maximumCapacity: The maximum capacity to allocate when the application is created. This is cumulative across all workers at any given point in time, not just when an application is created. No new resources will be created once any one of the defined limits is hit.
    ///   - monitoringConfiguration: The configuration setting for monitoring.
    ///   - name: The name of the application.
    ///   - networkConfiguration: The network configuration for customer VPC connectivity.
    ///   - releaseLabel: The Amazon EMR release associated with the application.
    ///   - runtimeConfiguration: The Configuration specifications to use when creating an application. Each configuration consists of a classification and properties. This configuration is applied to all the job runs submitted under the application.
    ///   - schedulerConfiguration: The scheduler configuration for batch and streaming jobs running on this application. Supported with release labels emr-7.0.0 and above.
    ///   - tags: The tags assigned to the application.
    ///   - type: The type of application you want to start, such as Spark or Hive.
    ///   - workerTypeSpecifications: The key-value pairs that specify worker type to WorkerTypeSpecificationInput. This parameter must contain all valid worker types for a Spark or Hive application. Valid worker types include Driver and Executor for Spark applications and HiveDriver and TezTask for Hive applications. You can either set image details in this parameter for each worker type, or in imageConfiguration for all worker types.
    ///   - logger: Logger use during operation
    @inlinable
    public func createApplication(
        architecture: Architecture? = nil,
        autoStartConfiguration: AutoStartConfig? = nil,
        autoStopConfiguration: AutoStopConfig? = nil,
        clientToken: String = CreateApplicationRequest.idempotencyToken(),
        identityCenterConfiguration: IdentityCenterConfigurationInput? = nil,
        imageConfiguration: ImageConfigurationInput? = nil,
        initialCapacity: [String: InitialCapacityConfig]? = nil,
        interactiveConfiguration: InteractiveConfiguration? = nil,
        maximumCapacity: MaximumAllowedResources? = nil,
        monitoringConfiguration: MonitoringConfiguration? = nil,
        name: String? = nil,
        networkConfiguration: NetworkConfiguration? = nil,
        releaseLabel: String,
        runtimeConfiguration: [Configuration]? = nil,
        schedulerConfiguration: SchedulerConfiguration? = nil,
        tags: [String: String]? = nil,
        type: String,
        workerTypeSpecifications: [String: WorkerTypeSpecificationInput]? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> CreateApplicationResponse {
        let input = CreateApplicationRequest(
            architecture: architecture, 
            autoStartConfiguration: autoStartConfiguration, 
            autoStopConfiguration: autoStopConfiguration, 
            clientToken: clientToken, 
            identityCenterConfiguration: identityCenterConfiguration, 
            imageConfiguration: imageConfiguration, 
            initialCapacity: initialCapacity, 
            interactiveConfiguration: interactiveConfiguration, 
            maximumCapacity: maximumCapacity, 
            monitoringConfiguration: monitoringConfiguration, 
            name: name, 
            networkConfiguration: networkConfiguration, 
            releaseLabel: releaseLabel, 
            runtimeConfiguration: runtimeConfiguration, 
            schedulerConfiguration: schedulerConfiguration, 
            tags: tags, 
            type: type, 
            workerTypeSpecifications: workerTypeSpecifications
        )
        return try await self.createApplication(input, logger: logger)
    }

    /// Deletes an application. An application has to be in a stopped or created state in order to be deleted.
    @Sendable
    @inlinable
    public func deleteApplication(_ input: DeleteApplicationRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> DeleteApplicationResponse {
        try await self.client.execute(
            operation: "DeleteApplication", 
            path: "/applications/{applicationId}", 
            httpMethod: .DELETE, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Deletes an application. An application has to be in a stopped or created state in order to be deleted.
    ///
    /// Parameters:
    ///   - applicationId: The ID of the application that will be deleted.
    ///   - logger: Logger use during operation
    @inlinable
    public func deleteApplication(
        applicationId: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> DeleteApplicationResponse {
        let input = DeleteApplicationRequest(
            applicationId: applicationId
        )
        return try await self.deleteApplication(input, logger: logger)
    }

    /// Displays detailed information about a specified application.
    @Sendable
    @inlinable
    public func getApplication(_ input: GetApplicationRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> GetApplicationResponse {
        try await self.client.execute(
            operation: "GetApplication", 
            path: "/applications/{applicationId}", 
            httpMethod: .GET, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Displays detailed information about a specified application.
    ///
    /// Parameters:
    ///   - applicationId: The ID of the application that will be described.
    ///   - logger: Logger use during operation
    @inlinable
    public func getApplication(
        applicationId: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> GetApplicationResponse {
        let input = GetApplicationRequest(
            applicationId: applicationId
        )
        return try await self.getApplication(input, logger: logger)
    }

    /// Creates and returns a URL that you can use to access the application UIs for a job run. For jobs in a running state, the application UI is a live user interface such as the Spark or Tez web UI. For completed jobs, the application UI is a persistent application user interface such as the Spark History Server or persistent Tez UI.  The URL is valid for one hour after you generate it. To access the application UI after that hour elapses, you must invoke the API again to generate a new URL.
    @Sendable
    @inlinable
    public func getDashboardForJobRun(_ input: GetDashboardForJobRunRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> GetDashboardForJobRunResponse {
        try await self.client.execute(
            operation: "GetDashboardForJobRun", 
            path: "/applications/{applicationId}/jobruns/{jobRunId}/dashboard", 
            httpMethod: .GET, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Creates and returns a URL that you can use to access the application UIs for a job run. For jobs in a running state, the application UI is a live user interface such as the Spark or Tez web UI. For completed jobs, the application UI is a persistent application user interface such as the Spark History Server or persistent Tez UI.  The URL is valid for one hour after you generate it. To access the application UI after that hour elapses, you must invoke the API again to generate a new URL.
    ///
    /// Parameters:
    ///   - accessSystemProfileLogs: Allows access to system profile logs for Lake Formation-enabled jobs. Default is false.
    ///   - applicationId: The ID of the application.
    ///   - attempt: An optimal parameter that indicates the amount of attempts for the job. If not specified, this value defaults to the attempt of the latest job.
    ///   - jobRunId: The ID of the job run.
    ///   - logger: Logger use during operation
    @inlinable
    public func getDashboardForJobRun(
        accessSystemProfileLogs: Bool? = nil,
        applicationId: String,
        attempt: Int? = nil,
        jobRunId: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> GetDashboardForJobRunResponse {
        let input = GetDashboardForJobRunRequest(
            accessSystemProfileLogs: accessSystemProfileLogs, 
            applicationId: applicationId, 
            attempt: attempt, 
            jobRunId: jobRunId
        )
        return try await self.getDashboardForJobRun(input, logger: logger)
    }

    /// Displays detailed information about a job run.
    @Sendable
    @inlinable
    public func getJobRun(_ input: GetJobRunRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> GetJobRunResponse {
        try await self.client.execute(
            operation: "GetJobRun", 
            path: "/applications/{applicationId}/jobruns/{jobRunId}", 
            httpMethod: .GET, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Displays detailed information about a job run.
    ///
    /// Parameters:
    ///   - applicationId: The ID of the application on which the job run is submitted.
    ///   - attempt: An optimal parameter that indicates the amount of attempts for the job. If not specified, this value defaults to the attempt of the latest job.
    ///   - jobRunId: The ID of the job run.
    ///   - logger: Logger use during operation
    @inlinable
    public func getJobRun(
        applicationId: String,
        attempt: Int? = nil,
        jobRunId: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> GetJobRunResponse {
        let input = GetJobRunRequest(
            applicationId: applicationId, 
            attempt: attempt, 
            jobRunId: jobRunId
        )
        return try await self.getJobRun(input, logger: logger)
    }

    /// Lists applications based on a set of parameters.
    @Sendable
    @inlinable
    public func listApplications(_ input: ListApplicationsRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListApplicationsResponse {
        try await self.client.execute(
            operation: "ListApplications", 
            path: "/applications", 
            httpMethod: .GET, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Lists applications based on a set of parameters.
    ///
    /// Parameters:
    ///   - maxResults: The maximum number of applications that can be listed.
    ///   - nextToken: The token for the next set of application results.
    ///   - states: An optional filter for application states. Note that if this filter contains multiple states, the resulting list will be grouped by the state.
    ///   - logger: Logger use during operation
    @inlinable
    public func listApplications(
        maxResults: Int? = nil,
        nextToken: String? = nil,
        states: [ApplicationState]? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListApplicationsResponse {
        let input = ListApplicationsRequest(
            maxResults: maxResults, 
            nextToken: nextToken, 
            states: states
        )
        return try await self.listApplications(input, logger: logger)
    }

    /// Lists all attempt of a job run.
    @Sendable
    @inlinable
    public func listJobRunAttempts(_ input: ListJobRunAttemptsRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListJobRunAttemptsResponse {
        try await self.client.execute(
            operation: "ListJobRunAttempts", 
            path: "/applications/{applicationId}/jobruns/{jobRunId}/attempts", 
            httpMethod: .GET, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Lists all attempt of a job run.
    ///
    /// Parameters:
    ///   - applicationId: The ID of the application for which to list job runs.
    ///   - jobRunId: The ID of the job run to list.
    ///   - maxResults: The maximum number of job run attempts to list.
    ///   - nextToken: The token for the next set of job run attempt results.
    ///   - logger: Logger use during operation
    @inlinable
    public func listJobRunAttempts(
        applicationId: String,
        jobRunId: String,
        maxResults: Int? = nil,
        nextToken: String? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListJobRunAttemptsResponse {
        let input = ListJobRunAttemptsRequest(
            applicationId: applicationId, 
            jobRunId: jobRunId, 
            maxResults: maxResults, 
            nextToken: nextToken
        )
        return try await self.listJobRunAttempts(input, logger: logger)
    }

    /// Lists job runs based on a set of parameters.
    @Sendable
    @inlinable
    public func listJobRuns(_ input: ListJobRunsRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListJobRunsResponse {
        try await self.client.execute(
            operation: "ListJobRuns", 
            path: "/applications/{applicationId}/jobruns", 
            httpMethod: .GET, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Lists job runs based on a set of parameters.
    ///
    /// Parameters:
    ///   - applicationId: The ID of the application for which to list the job run.
    ///   - createdAtAfter: The lower bound of the option to filter by creation date and time.
    ///   - createdAtBefore: The upper bound of the option to filter by creation date and time.
    ///   - maxResults: The maximum number of job runs that can be listed.
    ///   - mode: The mode of the job runs to list.
    ///   - nextToken: The token for the next set of job run results.
    ///   - states: An optional filter for job run states. Note that if this filter contains multiple states, the resulting list will be grouped by the state.
    ///   - logger: Logger use during operation
    @inlinable
    public func listJobRuns(
        applicationId: String,
        createdAtAfter: Date? = nil,
        createdAtBefore: Date? = nil,
        maxResults: Int? = nil,
        mode: JobRunMode? = nil,
        nextToken: String? = nil,
        states: [JobRunState]? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListJobRunsResponse {
        let input = ListJobRunsRequest(
            applicationId: applicationId, 
            createdAtAfter: createdAtAfter, 
            createdAtBefore: createdAtBefore, 
            maxResults: maxResults, 
            mode: mode, 
            nextToken: nextToken, 
            states: states
        )
        return try await self.listJobRuns(input, logger: logger)
    }

    /// Lists the tags assigned to the resources.
    @Sendable
    @inlinable
    public func listTagsForResource(_ input: ListTagsForResourceRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListTagsForResourceResponse {
        try await self.client.execute(
            operation: "ListTagsForResource", 
            path: "/tags/{resourceArn}", 
            httpMethod: .GET, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Lists the tags assigned to the resources.
    ///
    /// Parameters:
    ///   - resourceArn: The Amazon Resource Name (ARN) that identifies the resource to list the tags for. Currently, the supported resources are Amazon EMR Serverless applications and job runs.
    ///   - logger: Logger use during operation
    @inlinable
    public func listTagsForResource(
        resourceArn: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListTagsForResourceResponse {
        let input = ListTagsForResourceRequest(
            resourceArn: resourceArn
        )
        return try await self.listTagsForResource(input, logger: logger)
    }

    /// Starts a specified application and initializes initial capacity if configured.
    @Sendable
    @inlinable
    public func startApplication(_ input: StartApplicationRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> StartApplicationResponse {
        try await self.client.execute(
            operation: "StartApplication", 
            path: "/applications/{applicationId}/start", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Starts a specified application and initializes initial capacity if configured.
    ///
    /// Parameters:
    ///   - applicationId: The ID of the application to start.
    ///   - logger: Logger use during operation
    @inlinable
    public func startApplication(
        applicationId: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> StartApplicationResponse {
        let input = StartApplicationRequest(
            applicationId: applicationId
        )
        return try await self.startApplication(input, logger: logger)
    }

    /// Starts a job run.
    @Sendable
    @inlinable
    public func startJobRun(_ input: StartJobRunRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> StartJobRunResponse {
        try await self.client.execute(
            operation: "StartJobRun", 
            path: "/applications/{applicationId}/jobruns", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Starts a job run.
    ///
    /// Parameters:
    ///   - applicationId: The ID of the application on which to run the job.
    ///   - clientToken: The client idempotency token of the job run to start. Its value must be unique for each request.
    ///   - configurationOverrides: The configuration overrides for the job run.
    ///   - executionIamPolicy: You can pass an optional IAM policy. The resulting job IAM role permissions will be an intersection of this policy and the policy associated with your job execution role.
    ///   - executionRoleArn: The execution role ARN for the job run.
    ///   - executionTimeoutMinutes: The maximum duration for the job run to run. If the job run runs beyond this duration, it will be automatically cancelled.
    ///   - jobDriver: The job driver for the job run.
    ///   - mode: The mode of the job run when it starts.
    ///   - name: The optional job run name. This doesn't have to be unique.
    ///   - retryPolicy: The retry policy when job run starts.
    ///   - tags: The tags assigned to the job run.
    ///   - logger: Logger use during operation
    @inlinable
    public func startJobRun(
        applicationId: String,
        clientToken: String = StartJobRunRequest.idempotencyToken(),
        configurationOverrides: ConfigurationOverrides? = nil,
        executionIamPolicy: JobRunExecutionIamPolicy? = nil,
        executionRoleArn: String,
        executionTimeoutMinutes: Int64? = nil,
        jobDriver: JobDriver? = nil,
        mode: JobRunMode? = nil,
        name: String? = nil,
        retryPolicy: RetryPolicy? = nil,
        tags: [String: String]? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> StartJobRunResponse {
        let input = StartJobRunRequest(
            applicationId: applicationId, 
            clientToken: clientToken, 
            configurationOverrides: configurationOverrides, 
            executionIamPolicy: executionIamPolicy, 
            executionRoleArn: executionRoleArn, 
            executionTimeoutMinutes: executionTimeoutMinutes, 
            jobDriver: jobDriver, 
            mode: mode, 
            name: name, 
            retryPolicy: retryPolicy, 
            tags: tags
        )
        return try await self.startJobRun(input, logger: logger)
    }

    /// Stops a specified application and releases initial capacity if configured. All scheduled and running jobs must be completed or cancelled before stopping an application.
    @Sendable
    @inlinable
    public func stopApplication(_ input: StopApplicationRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> StopApplicationResponse {
        try await self.client.execute(
            operation: "StopApplication", 
            path: "/applications/{applicationId}/stop", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Stops a specified application and releases initial capacity if configured. All scheduled and running jobs must be completed or cancelled before stopping an application.
    ///
    /// Parameters:
    ///   - applicationId: The ID of the application to stop.
    ///   - logger: Logger use during operation
    @inlinable
    public func stopApplication(
        applicationId: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> StopApplicationResponse {
        let input = StopApplicationRequest(
            applicationId: applicationId
        )
        return try await self.stopApplication(input, logger: logger)
    }

    /// Assigns tags to resources. A tag is a label that you assign to an Amazon Web Services resource. Each tag consists of a key and an optional value, both of which you define. Tags enable you to categorize your Amazon Web Services resources by attributes such as purpose, owner, or environment. When you have many resources of the same type, you can quickly identify a specific resource based on the tags you've assigned to it.
    @Sendable
    @inlinable
    public func tagResource(_ input: TagResourceRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> TagResourceResponse {
        try await self.client.execute(
            operation: "TagResource", 
            path: "/tags/{resourceArn}", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Assigns tags to resources. A tag is a label that you assign to an Amazon Web Services resource. Each tag consists of a key and an optional value, both of which you define. Tags enable you to categorize your Amazon Web Services resources by attributes such as purpose, owner, or environment. When you have many resources of the same type, you can quickly identify a specific resource based on the tags you've assigned to it.
    ///
    /// Parameters:
    ///   - resourceArn: The Amazon Resource Name (ARN) that identifies the resource to list the tags for. Currently, the supported resources are Amazon EMR Serverless applications and job runs.
    ///   - tags: The tags to add to the resource. A tag is an array of key-value pairs.
    ///   - logger: Logger use during operation
    @inlinable
    public func tagResource(
        resourceArn: String,
        tags: [String: String],
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> TagResourceResponse {
        let input = TagResourceRequest(
            resourceArn: resourceArn, 
            tags: tags
        )
        return try await self.tagResource(input, logger: logger)
    }

    /// Removes tags from resources.
    @Sendable
    @inlinable
    public func untagResource(_ input: UntagResourceRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> UntagResourceResponse {
        try await self.client.execute(
            operation: "UntagResource", 
            path: "/tags/{resourceArn}", 
            httpMethod: .DELETE, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Removes tags from resources.
    ///
    /// Parameters:
    ///   - resourceArn: The Amazon Resource Name (ARN) that identifies the resource to list the tags for. Currently, the supported resources are Amazon EMR Serverless applications and job runs.
    ///   - tagKeys: The keys of the tags to be removed.
    ///   - logger: Logger use during operation
    @inlinable
    public func untagResource(
        resourceArn: String,
        tagKeys: [String],
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> UntagResourceResponse {
        let input = UntagResourceRequest(
            resourceArn: resourceArn, 
            tagKeys: tagKeys
        )
        return try await self.untagResource(input, logger: logger)
    }

    /// Updates a specified application. An application has to be in a stopped or created state in order to be updated.
    @Sendable
    @inlinable
    public func updateApplication(_ input: UpdateApplicationRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> UpdateApplicationResponse {
        try await self.client.execute(
            operation: "UpdateApplication", 
            path: "/applications/{applicationId}", 
            httpMethod: .PATCH, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Updates a specified application. An application has to be in a stopped or created state in order to be updated.
    ///
    /// Parameters:
    ///   - applicationId: The ID of the application to update.
    ///   - architecture: The CPU architecture of an application.
    ///   - autoStartConfiguration: The configuration for an application to automatically start on job submission.
    ///   - autoStopConfiguration: The configuration for an application to automatically stop after a certain amount of time being idle.
    ///   - clientToken: The client idempotency token of the application to update. Its value must be unique for each request.
    ///   - identityCenterConfiguration: Specifies the IAM Identity Center configuration used to enable or disable trusted identity propagation. When provided, this configuration determines how the application interacts with IAM Identity Center for user authentication and access control.
    ///   - imageConfiguration: The image configuration to be used for all worker types. You can either set this parameter or imageConfiguration for each worker type in WorkerTypeSpecificationInput.
    ///   - initialCapacity: The capacity to initialize when the application is updated.
    ///   - interactiveConfiguration: The interactive configuration object that contains new interactive use cases when the application is updated.
    ///   - maximumCapacity: The maximum capacity to allocate when the application is updated. This is cumulative across all workers at any given point in time during the lifespan of the application. No new resources will be created once any one of the defined limits is hit.
    ///   - monitoringConfiguration: The configuration setting for monitoring.
    ///   - networkConfiguration: 
    ///   - releaseLabel: The Amazon EMR release label for the application. You can change the release label to use a different release of Amazon EMR.
    ///   - runtimeConfiguration: The Configuration specifications to use when updating an application. Each configuration consists of a classification and properties. This configuration is applied across all the job runs submitted under the application.
    ///   - schedulerConfiguration: The scheduler configuration for batch and streaming jobs running on this application. Supported with release labels emr-7.0.0 and above.
    ///   - workerTypeSpecifications: The key-value pairs that specify worker type to WorkerTypeSpecificationInput. This parameter must contain all valid worker types for a Spark or Hive application. Valid worker types include Driver and Executor for Spark applications and HiveDriver and TezTask for Hive applications. You can either set image details in this parameter for each worker type, or in imageConfiguration for all worker types.
    ///   - logger: Logger use during operation
    @inlinable
    public func updateApplication(
        applicationId: String,
        architecture: Architecture? = nil,
        autoStartConfiguration: AutoStartConfig? = nil,
        autoStopConfiguration: AutoStopConfig? = nil,
        clientToken: String = UpdateApplicationRequest.idempotencyToken(),
        identityCenterConfiguration: IdentityCenterConfigurationInput? = nil,
        imageConfiguration: ImageConfigurationInput? = nil,
        initialCapacity: [String: InitialCapacityConfig]? = nil,
        interactiveConfiguration: InteractiveConfiguration? = nil,
        maximumCapacity: MaximumAllowedResources? = nil,
        monitoringConfiguration: MonitoringConfiguration? = nil,
        networkConfiguration: NetworkConfiguration? = nil,
        releaseLabel: String? = nil,
        runtimeConfiguration: [Configuration]? = nil,
        schedulerConfiguration: SchedulerConfiguration? = nil,
        workerTypeSpecifications: [String: WorkerTypeSpecificationInput]? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> UpdateApplicationResponse {
        let input = UpdateApplicationRequest(
            applicationId: applicationId, 
            architecture: architecture, 
            autoStartConfiguration: autoStartConfiguration, 
            autoStopConfiguration: autoStopConfiguration, 
            clientToken: clientToken, 
            identityCenterConfiguration: identityCenterConfiguration, 
            imageConfiguration: imageConfiguration, 
            initialCapacity: initialCapacity, 
            interactiveConfiguration: interactiveConfiguration, 
            maximumCapacity: maximumCapacity, 
            monitoringConfiguration: monitoringConfiguration, 
            networkConfiguration: networkConfiguration, 
            releaseLabel: releaseLabel, 
            runtimeConfiguration: runtimeConfiguration, 
            schedulerConfiguration: schedulerConfiguration, 
            workerTypeSpecifications: workerTypeSpecifications
        )
        return try await self.updateApplication(input, logger: logger)
    }
}

extension EMRServerless {
    /// Initializer required by `AWSService.with(middlewares:timeout:byteBufferAllocator:options)`. You are not able to use this initializer directly as there are not public
    /// initializers for `AWSServiceConfig.Patch`. Please use `AWSService.with(middlewares:timeout:byteBufferAllocator:options)` instead.
    public init(from: EMRServerless, patch: AWSServiceConfig.Patch) {
        self.client = from.client
        self.config = from.config.with(patch: patch)
    }
}

// MARK: Paginators

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension EMRServerless {
    /// Return PaginatorSequence for operation ``listApplications(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func listApplicationsPaginator(
        _ input: ListApplicationsRequest,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<ListApplicationsRequest, ListApplicationsResponse> {
        return .init(
            input: input,
            command: self.listApplications,
            inputKey: \ListApplicationsRequest.nextToken,
            outputKey: \ListApplicationsResponse.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``listApplications(_:logger:)``.
    ///
    /// - Parameters:
    ///   - maxResults: The maximum number of applications that can be listed.
    ///   - states: An optional filter for application states. Note that if this filter contains multiple states, the resulting list will be grouped by the state.
    ///   - logger: Logger used for logging
    @inlinable
    public func listApplicationsPaginator(
        maxResults: Int? = nil,
        states: [ApplicationState]? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<ListApplicationsRequest, ListApplicationsResponse> {
        let input = ListApplicationsRequest(
            maxResults: maxResults, 
            states: states
        )
        return self.listApplicationsPaginator(input, logger: logger)
    }

    /// Return PaginatorSequence for operation ``listJobRunAttempts(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func listJobRunAttemptsPaginator(
        _ input: ListJobRunAttemptsRequest,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<ListJobRunAttemptsRequest, ListJobRunAttemptsResponse> {
        return .init(
            input: input,
            command: self.listJobRunAttempts,
            inputKey: \ListJobRunAttemptsRequest.nextToken,
            outputKey: \ListJobRunAttemptsResponse.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``listJobRunAttempts(_:logger:)``.
    ///
    /// - Parameters:
    ///   - applicationId: The ID of the application for which to list job runs.
    ///   - jobRunId: The ID of the job run to list.
    ///   - maxResults: The maximum number of job run attempts to list.
    ///   - logger: Logger used for logging
    @inlinable
    public func listJobRunAttemptsPaginator(
        applicationId: String,
        jobRunId: String,
        maxResults: Int? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<ListJobRunAttemptsRequest, ListJobRunAttemptsResponse> {
        let input = ListJobRunAttemptsRequest(
            applicationId: applicationId, 
            jobRunId: jobRunId, 
            maxResults: maxResults
        )
        return self.listJobRunAttemptsPaginator(input, logger: logger)
    }

    /// Return PaginatorSequence for operation ``listJobRuns(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func listJobRunsPaginator(
        _ input: ListJobRunsRequest,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<ListJobRunsRequest, ListJobRunsResponse> {
        return .init(
            input: input,
            command: self.listJobRuns,
            inputKey: \ListJobRunsRequest.nextToken,
            outputKey: \ListJobRunsResponse.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``listJobRuns(_:logger:)``.
    ///
    /// - Parameters:
    ///   - applicationId: The ID of the application for which to list the job run.
    ///   - createdAtAfter: The lower bound of the option to filter by creation date and time.
    ///   - createdAtBefore: The upper bound of the option to filter by creation date and time.
    ///   - maxResults: The maximum number of job runs that can be listed.
    ///   - mode: The mode of the job runs to list.
    ///   - states: An optional filter for job run states. Note that if this filter contains multiple states, the resulting list will be grouped by the state.
    ///   - logger: Logger used for logging
    @inlinable
    public func listJobRunsPaginator(
        applicationId: String,
        createdAtAfter: Date? = nil,
        createdAtBefore: Date? = nil,
        maxResults: Int? = nil,
        mode: JobRunMode? = nil,
        states: [JobRunState]? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<ListJobRunsRequest, ListJobRunsResponse> {
        let input = ListJobRunsRequest(
            applicationId: applicationId, 
            createdAtAfter: createdAtAfter, 
            createdAtBefore: createdAtBefore, 
            maxResults: maxResults, 
            mode: mode, 
            states: states
        )
        return self.listJobRunsPaginator(input, logger: logger)
    }
}

extension EMRServerless.ListApplicationsRequest: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> EMRServerless.ListApplicationsRequest {
        return .init(
            maxResults: self.maxResults,
            nextToken: token,
            states: self.states
        )
    }
}

extension EMRServerless.ListJobRunAttemptsRequest: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> EMRServerless.ListJobRunAttemptsRequest {
        return .init(
            applicationId: self.applicationId,
            jobRunId: self.jobRunId,
            maxResults: self.maxResults,
            nextToken: token
        )
    }
}

extension EMRServerless.ListJobRunsRequest: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> EMRServerless.ListJobRunsRequest {
        return .init(
            applicationId: self.applicationId,
            createdAtAfter: self.createdAtAfter,
            createdAtBefore: self.createdAtBefore,
            maxResults: self.maxResults,
            mode: self.mode,
            nextToken: token,
            states: self.states
        )
    }
}
